
package org.dyndns.cooland.updater;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;

import org.dyndns.cooland.updater.db.model.Bean;

public class Loader implements Runnable, InetLoader {
	
	private boolean					executed	= false;
	protected InetLoaderCallback	ui;
	private boolean					canceled	= false;
	private String					url;
	private int						connect_timeout;
	private int						read_timeout;
	private Proxy					proxy;
	String							file_path;
	Bean							bean;
	
	public Loader (InetLoaderCallback ui, String url, String file_path,
			Proxy proxy, int connect_timeout, int read_timeout, Bean bean) {

		this.ui = ui;
		this.url = url;
		this.proxy = proxy;
		this.connect_timeout = connect_timeout;
		this.read_timeout = read_timeout;
		this.file_path = file_path;
		this.bean = bean;
	}
	
	public synchronized void execute() {

		if (executed){
			throw new IllegalStateException("Loader is already executed");
		}
		executed = true;
		Thread t = new Thread(this, "Loader thread");
		t.start();
	}
	
	public void run() {

		ui.startLoading();
		try{
			URL inet_url = new URL(url);
			URLConnection urlConn = inet_url.openConnection(proxy);
			int size = urlConn.getContentLength();
			// long mod_time = urlConn.getLastModified();
			urlConn.setConnectTimeout(connect_timeout);
			urlConn.setReadTimeout(read_timeout);
			try{
				urlConn.setDoInput(true);
				urlConn.setUseCaches(false);
			}
			catch (IllegalStateException e){
				// already connected
			}
			InputStream is = null;
			is = urlConn.getInputStream();
			// TODO only for testing
			byte[] buffer = new byte[10];
			// byte[] buffer = new byte[8 * 1024];
			OutputStream output = new FileOutputStream(file_path);
			try{
				// while (!isCanceled()){
				int bytesRead;
				int totalRead = 0;
				while ((bytesRead = is.read(buffer)) != -1){
					output.write(buffer, 0, bytesRead);
					totalRead += bytesRead;
					ui.setProgress(totalRead * 100 / size);
					// TODO remove pause, only for testing
					try{
						Thread.sleep(100);
					}
					catch (InterruptedException e){}
				}
				
				// }
			}
			finally{
				output.close();
			}
			
			if (is != null){
				is.close();
			}
			if ((new File(file_path)).length() != size){
				// error while downloading (may be bad inet connection)
				ui.showError("File " + url
						+ " does not downloaded correctly, size not equal");
			}
		}
		catch (Exception e){
			e.printStackTrace();
			ui.showError("Error while downloading file " + url + ": \n"
					+ e.getMessage());
		}
		ui.stopLoading(file_path, url, bean);
	}
	
	public synchronized void cancel() {

		canceled = true;
	}
	
	private synchronized boolean isCanceled() {

		return canceled;
	}
}
